package com.example.controller;

import com.example.config.WechatConfig;
import com.example.entity.User;
import com.example.service.RedisAuthService;
import com.example.service.UserService;
import com.example.util.JsonUtil;
import com.example.util.OkHttpUtil;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;

@Controller
public class WechatAuthController {
    @Autowired
    private WechatConfig wechatConfig;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisAuthService redisAuthService;

    @GetMapping("/home")
    public String home(HttpSession session, Model model) {
        User user = redisAuthService.getLoginUser(session.getId());
        model.addAttribute("user", user);
        return "home";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:/login";
    }

    @GetMapping(value = "/check-login", produces = "application/json")
    @ResponseBody
    public Map<String, Boolean> checkLogin(HttpSession session) {
        User user = (User) session.getAttribute("currentUser");
        return Collections.singletonMap("loggedIn", user != null);
    }

    @GetMapping("/login")
    public String login(HttpSession session, Model model) {
        return "login";
    }


    @GetMapping("/generateQrUrl")
    public String login() {
        return "redirect:" + generateQrUrl();
    }


    private String generateQrUrl() {

        String state = UUID.randomUUID().toString();

        String redirectUri = URLEncoder.encode(wechatConfig.getCallback(), StandardCharsets.UTF_8);
        String qrUrl = String.format(
                "https://open.weixin.qq.com/connect/qrconnect?" +
                        "appid=%s&redirect_uri=%s&response_type=code" +
                        "&scope=snsapi_login&state=%s#wechat_redirect",
                wechatConfig.getAppId(), redirectUri, state
        );

        return qrUrl;
    }


    @GetMapping("/wechat-qrcode")
    public ResponseEntity<byte[]> proxyQrImage() throws IOException {

        String state = UUID.randomUUID().toString();

        String redirectUri = URLEncoder.encode(wechatConfig.getCallback(), StandardCharsets.UTF_8);
        String qrUrl = String.format(
                "https://open.weixin.qq.com/connect/qrconnect?" +
                        "appid=%s&redirect_uri=%s&response_type=code" +
                        "&scope=snsapi_login&state=%s#wechat_redirect",
                wechatConfig.getAppId(), redirectUri, state
        );

        URL url = new URL(qrUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Referer", "https://open.weixin.qq.com"); // 伪造合法Referer
        byte[] imageBytes = conn.getInputStream().readAllBytes();
        return ResponseEntity.ok()
                .contentType(MediaType.IMAGE_JPEG) // 根据实际图片类型调整
                .body(imageBytes);
    }


    // 微信回调处理
    @GetMapping("/callback")
    public String callback(
            @RequestParam String code,
            @RequestParam String state,
            HttpSession session,
            Model model
    ) throws IOException {
        System.out.println("=== 微信回调开始 ===");
        System.out.println("接收参数 - code: " + code);
        System.out.println("接收参数 - state: " + state);
        System.out.println("Session ID: " + session.getId());

        // 1. 校验state安全性
        System.out.println("验证state参数...");
        Object sessionState = session.getAttribute("wechat_state");
        System.out.println("Session中的state: " + sessionState);
        if (!state.equals(sessionState)) {
            System.err.println("State参数校验失败: 请求state=" + state + ", 会话state=" + sessionState);
            throw new RuntimeException("State参数校验失败");
        }
        System.out.println("State验证通过");

        // 2. 换取access_token
        System.out.println("准备获取access_token...");
        String tokenUrl = String.format(
                "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                        "appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                wechatConfig.getAppId(), wechatConfig.getAppSecret(), code
        );
        System.out.println("Token请求URL: " + tokenUrl);
        String tokenJson = OkHttpUtil.get(tokenUrl);
        System.out.println("Token响应: " + tokenJson);
        JsonNode tokenNode = JsonUtil.parse(tokenJson);
        System.out.println("解析Token响应: access_token=" + tokenNode.get("access_token") +
                ", openid=" + tokenNode.get("openid"));

        // 3. 获取用户信息
        System.out.println("准备获取用户信息...");
        String userInfoUrl = String.format(
                "https://api.weixin.qq.com/sns/userinfo?" +
                        "access_token=%s&openid=%s",
                tokenNode.get("access_token").asText(),
                tokenNode.get("openid").asText()
        );
        System.out.println("用户信息请求URL: " + userInfoUrl);
        String userJson = OkHttpUtil.get(userInfoUrl);
        System.out.println("用户信息响应: " + userJson);
        JsonNode userNode = JsonUtil.parse(userJson);
        System.out.println("解析用户信息: nickname=" + userNode.get("nickname") +
                ", headimgurl=" + userNode.get("headimgurl"));

        // 4. 处理用户登录
        System.out.println("处理用户登录...");
        User user = userService.createOrUpdate(
                userNode.get("openid").asText(),
                userNode.get("nickname").asText(),
                userNode.get("headimgurl").asText()
        );
        System.out.println("用户信息处理完成: " + user);

        // 5. 存储登录态
        System.out.println("存储登录状态...");
        session.setAttribute("currentUser", user);
        redisAuthService.saveLoginStatus(
                session.getId(),
                user.getWechatOpenid(),
                user.getNickname(),
                user.getAvatar()
        );
        System.out.println("=== 微信回调处理完成 ===");
        return "redirect:/home";
    }
}